

#include <ell/vec.h>

#include <assert.h>
#include <stdio.h>
#include <string.h>

void ell__vec_init(struct ell_vec_core* core, void** data)
{
    assert(core != 0);
    assert(data != 0);

    core->capacity = 0;
    core->size = 0;
    *data = 0;
}

void ell__vec_ensure_capacity(struct ell_vec_core* core, void** data, size_t element_size)
{
    assert(core != 0);
    assert(data != 0);

    if (core->size >= core->capacity) {
        size_t new_capacity = core->capacity ? 2 * core->capacity : 2;
        ell__vec_reserve(core, data, element_size, new_capacity);
    }
}

void ell__vec_reset(struct ell_vec_core* core, void** data)
{
    assert(core != 0);
    assert(data != 0);

    if (*data != 0) {
        free(*data);
    }

    ell__vec_init(core, data);
}

void ell__vec_reserve(struct ell_vec_core* core, void** data, size_t element_size, size_t elements)
{
    assert(core != 0);
    assert(data != 0);

    if (core->capacity < elements) {
        *data = realloc(*data, elements * element_size);
        core->capacity = elements;
    }
}

void ell__vec_resize(struct ell_vec_core* core, void** data, size_t element_size, size_t elements)
{
    assert(core != 0);
    assert(data != 0);

    if (core->capacity < elements) {
        ell__vec_reserve(core, data, element_size, elements);
    }

    core->size = elements;
}

void ell__vec_fill_from_first(struct ell_vec_core* core, void* data, size_t element_size)
{
    void* src = data;
    unsigned char* dst = ((unsigned char*)data) + element_size;
    for (size_t i = 1; i < core->size; i++) {
        memcpy(dst, src, element_size);
        dst += element_size;
    }
}
